import { ElMessage } from "element-plus";
import CryptoJs from 'crypto-js'

// const MAX_FILE_SIZE = 10 * 1024 * 1024; // 最大文件大小
// const CHUNK_SIZE = 3 * 1024 * 1024; // 分块文件大小
// const CHUNK_HEADER = new Uint8Array([70, 67, 72, 75]); // "FCHK"
// const SMALL_FILE_HEADER = new Uint8Array([83, 77, 76, 70]); // "SMLF"



// 创建文件唯一标识符
export function generateFixedLengthKey(fileName: string, length: number): string {
    // 使用文件名的哈希值作为唯一标识符的一部分
    const hash = CryptoJs.SHA256(fileName).toString(CryptoJs.enc.Hex);  // 生成 64 位的十六进制哈希值
    // 截取哈希值的前 10 个字符
    const hashSubString = hash.substring(0, 10);
    // 使用时间戳和随机数生成唯一性部分
    const timeStamp = Date.now().toString(36);  // 将时间戳转换为 36 进制字符串
    const randomString = Math.random().toString(36).substring(2);   // 随机字符串

    const combined = timeStamp + randomString + hashSubString;  // 结合时间戳、随机数和文件名哈希、文件名
    // 截取或填充到指定长度
    return combined.substring(0, length).padEnd(length, 'x');
}
3
// 处理小文件的函数
export function handleSmallFile(websocket: WebSocket, file: File, fileMetadaMap: any, fileHeader: Uint8Array, temporaryFIleInfo: any) {
    const reader = new FileReader();
    reader.onload = (e): void => {
        if (e.target && e.target.result) {
            const fileContent = e.target.result as ArrayBuffer;
            let mimeType = fileMetadaMap.mimeType;
            /* 1️⃣ 先发送元数据到后端（让后端落地到聊天） */
            sendBinaryMessage(websocket, fileMetadaMap, 'metadata');
            // if (fileMetadaMap.mimeType.startsWith("image")) {
                // 根据文件内存生成一个blob文件（只是临时展示在页面上，还会在后端处理）
                // 这里需要先将ArrayBuffer转换为一个Blob，并指定文件的MIME类型
                // const blob = new Blob([fileContent], { type: file.type });
                // const blobUrl = URL.createObjectURL(blob);
            // }
            // 构建二进制消息并发送
            const message = createBinaryMessage(fileHeader, fileContent);
            // 发送二进制消息
            sendBinaryMessage(websocket, message, 'binaryMessage');

        }
    }

    reader.onerror = (e): void => {
        console.error(e)
    }

    reader.readAsArrayBuffer(file);

}

// 处理文件分块的函数
export function handleChunkFile(websocket: WebSocket, file: File, fileMetadataMap: any, totalChunks: number) {
    let currentChunk = 0;
    const CHUNK_SIZE = 3 * 1024 * 1024; // 分块大小：3MB

    // 对于分片传输的数据先发送元数据信息
    sendBinaryMessage(websocket, fileMetadataMap, 'metadata');

    const readChunk = (): void => {
        const start = currentChunk * CHUNK_SIZE;
        const end = Math.min(start + CHUNK_SIZE, file.size);
        const chunk = file.slice(start, end);

        const reader = new FileReader();
        reader.onload = (e): void => {
            if (e.target && e.target.result) {
                const chunkContent = e.target.result as ArrayBuffer;

                // 构造分块消息
                const fileType = "FCHK"; // 文件类型
                const fileKey = fileMetadataMap.fileKey; // 文件唯一标识
                const chunkIndex = currentChunk; // 当前分块编号

                // 创建二进制消息
                const message = new ArrayBuffer(32 + chunkContent.byteLength);
                const view = new DataView(message);

                // 写入文件类型     四个字节
                for (let i = 0; i < fileType.length; i++) {
                    view.setUint8(i, fileType.charCodeAt(i));
                }

                // 写入文件唯一标识
                for (let i = 0; i < fileKey.length; i++) {
                    view.setUint8(4 + i, fileKey.charCodeAt(i));
                }

                // 写入总分块数和当前分块编号   各4字节
                view.setUint32(24, totalChunks);
                view.setUint32(28, chunkIndex);

                // 写入分块数据
                const chunkArray = new Uint8Array(chunkContent);
                const messageArray = new Uint8Array(message);
                messageArray.set(chunkArray, 32);


                // 发送二进制消息
                sendBinaryMessage(websocket, message, 'binaryMessage');

                // 处理下一个分块
                currentChunk++;
                if (currentChunk < totalChunks) {
                    readChunk();
                } else {
                    console.log("文件分块发送完成");
                }
            }
        };

        reader.onerror = (e): void => {
            console.error(e);
            ElMessage.error("文件读取失败，请检查文件是否损坏或网络问题");
        };

        reader.readAsArrayBuffer(chunk);
    };

    // 启动文件读取过程
    readChunk();
}
// 发送文件消息的函数
function sendBinaryMessage(websocket: WebSocket, message: any, messageType: string) {
    if (websocket && websocket.readyState === WebSocket.OPEN) {
        if (messageType === 'metadata') {
            websocket.send(JSON.stringify(message));
        } else {
            websocket.send(message)
        }
    } else {
        console.error("WebSocket未建立");
        ElMessage.error("WebSocket未建立");
    }
}

// 创建二进制消息的函数
function createBinaryMessage(fileHeader: Uint8Array, content: ArrayBuffer): ArrayBuffer {
    // 确保 fileHeader 是 Uint8Array 类型
    if (!(fileHeader instanceof Uint8Array)) {
        throw new TypeError("fileHeader must be a Uint8Array");
    }

    // 获取内容的字节长度
    const contentLength = content.byteLength;

    // 创建最终的二进制消息
    const totalLength = fileHeader.length + contentLength;
    const messageBuffer = new Uint8Array(totalLength);

    // 写入文件头
    messageBuffer.set(fileHeader, 0);

    // 写入文件内容
    messageBuffer.set(new Uint8Array(content), fileHeader.length);

    return messageBuffer.buffer; // 返回 ArrayBuffer
}

